<template>
  <div ref="baseLoadPageRef" class="base-load-page" :style="loadPageStyle">
    <div v-if="$slots.head" class="head-fixed-box" :style="{ padding: newPadding, paddingBottom: '0px' }">
      <slot name="head"></slot>
    </div>
    <div class="base-load-page-subject">
      <div v-if="loadState === true" style="width: 100%; height: 100%" :style="{ padding: newPadding }">
        <base-skeleton style="height: 100%"></base-skeleton>
      </div>
      <template v-else>
        <base-empty
          v-if="loadState !== false"
          :style="{ padding: newPadding }"
          style="height: 100%"
          :description="description || ''"
          :imageSize="imageSize"
          :loadState="loadState as Exclude<$LoadState, boolean>"
          :pageLoadButton="pageLoadButton"
        ></base-empty>
        <div
          v-else
          style="width: 100%; height: 100%"
          :style="{ padding: newPadding, paddingTop: $slots.head ? '0px' : newPadding, paddingBottom: $slots.foot ? '0px' : newPadding }"
        >
          <slot></slot>
        </div>
      </template>
    </div>
    <div v-if="$slots.foot && loadState === false" class="foot-fixed-box" :style="{ padding: newPadding, paddingTop: '0px' }">
      <slot name="foot"></slot>
    </div>
  </div>
</template>

<script setup lang="ts">
  import type { PropType } from 'vue';
  import scss from '@/styles/module/export.module.scss';

  const props = defineProps({
    /** 当前状态 */
    loadState: { type: [String, Boolean] as PropType<$LoadState>, default: 'null' }, // true 加载中, false 加载完成, 其他代表加载失败
    /** 组件的内边距 */
    padding: { type: Number, default: parseInt(scss.appPagePadding || '') },
    /** 当前状态 */
    margin: { type: Number, default: parseInt(scss.appPagePadding || '') },
    /** 当前状态 */
    width: { type: Number as PropType<number | undefined>, default: undefined },
    /** 组件的高度 */
    height: { type: Number as PropType<number | undefined>, default: undefined },
    /** 背景颜色 */
    boxShadow: { type: String, default: 'var(--my-box-shadow-fill)' },
    /** 背景颜色 */
    background: { type: String, default: 'var(--el-bg-color)' },
    /** 异常状态下的提示文字 */
    description: { type: String, default: '' },
    /** 异常状态下的提示图标的大小 */
    imageSize: { type: Number, default: 280 },
    /** 异常状态下的自定义操作按钮 */
    pageLoadButton: { type: Array as PropType<$PageLoadButton[]>, default: () => [] }, // 自定义按钮 [{text:'去登录',callBack:()=>{} }]
  });

  defineSlots<{
    /** 主体内容 */
    default: () => void;
    /** 头部 */
    head?: () => void;
    /** 底部 */
    foot?: () => void;
  }>();

  const newPadding = computed(() => `${props.padding}px`);

  /** 样式 */
  const loadPageStyle = computed(() => {
    const stye = {
      '--load-page-height': `calc(100vh - ${scss.appHeaderHeight || '0px'} - ${props.margin * 2}px)`,
      'background': props.background,
      'width': typeof props.width === 'number' && props.width > 0 ? `${props.width}px` : `calc(100% - ${props.margin * 2}px)`,
      'height': typeof props.height === 'number' && props.height > 0 ? `${props.height}px` : 'var(--load-page-height)',
      'margin': `${props.margin}px`,
      'box-shadow': props.boxShadow,
    };
    return stye;
  });

  const baseLoadPageRef = ref<HTMLDivElement | null>(null);

  /**
   * 得到宽度
   */
  function getWidth() {
    return baseLoadPageRef.value?.clientWidth;
  }

  /**
   * 得到高度 (注意是减去padding的高度)
   */
  function getHeight() {
    return (baseLoadPageRef.value?.clientHeight || 1000) - props.padding * 2;
  }
  defineExpose({ getWidth, getHeight });
</script>

<style scoped lang="scss">
  .base-load-page {
    @include flex(column, nowrap, flex-start, flex-start, flex-start);
    box-sizing: border-box;
    overflow: hidden;
    background: $c-bg-block;
    border-radius: 8px;
    box-shadow: var(--my-box-shadow-fill);

    .head-fixed-box {
      width: 100%;
    }

    .base-load-page-subject {
      flex: 1;
      width: 100%;
      height: 100%;
      max-height: 100%;
      overflow-y: hidden;
    }

    .foot-fixed-box {
      width: 100%;
    }
  }
</style>
